package com.wind.utils.cipher;


import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;

/**
 * <p>
 *    DES（Data Encryption Standard）
 * 历史：DES是在1977年被美国国家标准局（NBS，现称NIST）正式采用的标准。
 * 密钥长度：DES使用56位密钥长度，这意味着它对密钥的每个64位块，实际上只使用56位，其余8位用作奇偶校验。
 * 安全性：由于DES的密钥长度较短，它已经不再被认为是安全的。现代计算能力可以在合理时间内破解DES加密。
 * 模式：DES可以以多种模式运行，包括ECB（电子密码本模式）、CBC（密码块链模式）和CFB（密码反馈模式）等。
 * </p>
 * @author wind
 * @date    2024-12-10 16:46
 * @version v1.0
 */
public class DesUtil {

    private static final String DES_KEY = "DES";

    /**
     * des加密
     * @param str 待加密对象
     * @param key 密钥 长度为8的倍数
     * @return
     */
    public static String encrypt(String str,String key) {
        String encryptedData = null;

        try {
            Cipher cipher = init(Cipher.ENCRYPT_MODE, key);
            // 加密，并把字节数组编码成字符串
            encryptedData = new sun.misc.BASE64Encoder().encode(cipher.doFinal(str.getBytes()));
        } catch (IllegalBlockSizeException | BadPaddingException e) {
            e.printStackTrace();
        }

        return encryptedData;
    }

    /**
     * des解密
     * @param str 待解密对象
     * @param key 密钥 长度为8的倍数
     * @return
     */
    public static String decrypt(String str,String key) {
        String decryptedData = null;
        try {
            Cipher cipher = init(Cipher.DECRYPT_MODE, key);
            // 把字符串解码为字节数组，并解密
            decryptedData = new String(cipher.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(str)));
        } catch (IllegalBlockSizeException | BadPaddingException | IOException e) {
            e.printStackTrace();
        }
        return decryptedData;
    }

    /**
     * 初始化加解密对象
     * @param mode
     * @param key 密钥 长度为8的倍数
     * @return
     */
    private static Cipher init(int mode, String key){
        Cipher cipher = null;
        try {
            SecureRandom sr = new SecureRandom();
            DESKeySpec desKey = new DESKeySpec(key.getBytes());

            // 创建一个密匙工厂，然后用它把DESKeySpec转换成一个SecretKey对象
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES_KEY);
            SecretKey secretKey = keyFactory.generateSecret(desKey);

            // 加解密对象
            cipher = Cipher.getInstance(DES_KEY);
            cipher.init(mode, secretKey, sr);

        } catch (InvalidKeyException | NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException e) {
            e.printStackTrace();
        }
        return cipher;
    }
}
